package com.qf.mp2301.controller;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.mp2301.entity.User;
import com.qf.mp2301.service.UserService;
import com.qf.mp2301.utils.RedisLock;
import com.qf.mp2301.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RedisLock redisLock;


    @GetMapping("/ip")
    public R testIP(HttpServletRequest request){

        String ip = request.getRemoteAddr();
        log.info("访问的ip地址为:{}",ip);
        return R.ok(ip);

    }

    @GetMapping("/vote")
    public R vote( String username,String phone ){


        log.info("手机号{}为候选人{}投票了",phone,username);

        // 把投票信息写入 Redis的 zset 结构中
        String key = "user:vote";
        redisTemplate.opsForZSet().incrementScore(key,username,1);

        // 查询该候选人得票数
        Double score = redisTemplate.opsForZSet().score(key, username);

        return R.ok(score);
    }


    /**
     * 随机抽取 count个用户
     * @param count
     * @return
     */
    @GetMapping("/pick/{count}")
    public R randomUserName(@PathVariable("count") Integer count){

        String key = "user:nameset";
        List list = redisTemplate.opsForSet().pop(key, count);

        return R.ok(list);

    }


    @GetMapping("/loadname")
    public R loadNamesToRedis(){

        //1.从t_user表中查询所有的用户的名字
//        List<User> userList = userService.list();

        List<Object> nameList = userService.listObjs(new QueryWrapper<User>().select("nickname"));

        // List<User> ---> List<String> ,String代表用户名
//        ArrayList<String> nameList = new ArrayList<>();
//        for (User user : userList) {
//            nameList.add(user.getName());
//        }

        //2. 写入redis的set数据结构中
        String key = "user:nameset";
        for (Object name : nameList) {
            redisTemplate.opsForSet().add(key,name);
        }

        return R.ok();

    }


    @GetMapping("/delete")
    public R delteUser(User user){

        return null;
    }

    /**
     * 修改用户信息
     * 注意，需要同时把缓存中的用户信息也修改
     * @param user
     * @return
     */
    @PostMapping("/update")
    public R updateUser(@RequestBody User user){

        return null;
    }

    @GetMapping("/login")
    public R login(String username, String password){
        //1. 省略一些细节
        String md5Pass = SecureUtil.md5(password);
        User user = userService.getOne(new QueryWrapper<User>().eq("nickname", username));
        String dbpassword = user.getPassword();

        if (md5Pass.equals(dbpassword)){
            System.out.println("密码校验通过了");
        }


        //2. 查询Redis中是否存在该用户，如果存在直接使用
        String key = "user:"+username;
        User o = (User) redisTemplate.opsForValue().get(key);

        if (o!=null){
            // 直接使用这个user对象
            System.out.println(o);
        }

        // 3. 省略其他逻辑
        R resultVo = new R();
        resultVo.setCode(1);
        resultVo.setMsg("登录成功");
        return resultVo;
    }

    /**
     * 面试题： @RequestBody 和 @ResponseBody 的区别
     * @param user
     * @return
     */
    @PostMapping("/regist")
    public R regist(@RequestBody User user){

        // 申请分布式锁
        redisLock.lock("user:regist:lock");

        //1. 省略一些细节

        //1.1 处理密码的转换，把密码原文 ---> MD5 HASH
        String password = user.getPassword();
        String md5Passwrod = SecureUtil.md5(password);

        user.setPassword(md5Passwrod);

        userService.save(user);

        //2. 写入Redis中
        String key = "user:"+user.getName();
        redisTemplate.opsForValue().set(key,user);

        redisLock.unlock("user:regist:lock");

        R resultVo = new R();
        resultVo.setCode(1);
        resultVo.setMsg("注册成功");
        resultVo.setData(user);
        return resultVo;
    }

}
